public without sharing class QuoteRegentController {

    public Boolean isErr {get;set;}
    public Boolean isSuccess {get;set;}
    public String msg {get;set;}

    public String paramJson {get;set;}
    public String resJson {get;set;}
    public String searchJson {get;set;}//检索用的参数


    public String parentId {get;set;}//体系客户ID

    public String accId {get;set;}//客户ID 

    public Boolean isSys {get;set;}//是否为三方体系
    public Boolean isBM {get;set;}//是否为三方体系

    public String pname {get;set;}//产品名称

    public String pserialNo {get;set;}//产品货号

    public String pnccode {get;set;}//产品存货编码

    public String pspec {get;set;}//规格

    public String pmodel {get;set;}//型号

    public String pbrand {get;set;}//品牌

    public String pcategory1 {get;set;}//产品一级分类

    public String pcategory0 {get;set;}//产品主分类

    public String papplication ;
    public String aplicableInstrumentcombbox {get;private set;}

    public String productType {get;set;}//产品类型

    public String lastMothOpt {get;set;}//判断 > < = no  上月平均价

    public Boolean isNew ;//是新建还是编辑

    public Set<Id> proSets ;///在体系总部存在的价目表的产品ID 集合

    public String company {get;private set;}//公司
    public String province {get;private set;}//省份

    public String dataOpts {get;private set;}//选项

    public String backId {get;set;}//返回的Id 

    public String qId ;//报价ID

    public String oppId ;///业务机会ID

    public Quote q {get;set;}//报价

    public String sealflag ;
    public String salescode {get;set;}
    public String companycode;

    public Boolean isCouldFindOverseaProduct;
    public Boolean isNeedSelectAccount {get; private set;}
    public Boolean isLookInvoiceDealerPrice{get;private set;}
    public String  accMapJson {get; private set;}

    public String  appAccId {get; private set;}

    public Boolean isGPO {get; private set;}



   // public String dataJson{get;private set;}
    public class ControllerException extends Exception {}

    public Opportunity opp {get; private set;}

    public QuoteRegentController(ApexPages.StandardController con) {
        resJson = '[]';
        isNew = false;
        isErr =false;
        oppId = System.currentPageReference().getParameters().get('oppId');
        qId = System.currentPageReference().getParameters().get('id');
        q = new Quote();
        isLookInvoiceDealerPrice =true;
        appAccId = null;
    }

    private void setErr(String message ){   
        isErr  =true;
        throw new ControllerException(message);

    }
    //是否为大家
    private boolean checkIsBM(Account acc){
        return acc.ParentId != null &&  acc.System__c == '大家检验';
    }
    ///初始化
    public void init(){
       User u = [select Profile.Name ,SubCompany__c from User where Id = :UserInfo.getUserId()];
        isCouldFindOverseaProduct = u.Profile.Name.contains('海外') ? true : false;
        isLookInvoiceDealerPrice  = u.Profile.Name != '销售部直销销售员';
        try{
            if(qId != null){//编辑
                q = [select Id, RecordType.DeveloperName, ApplicableCustomers__r.Name,Opportunity.Owner.PriceProvince__c,
                 ApplicableCustomers__c,Opportunity.RecordType.DeveloperName,Name,Status,OpportunityId,Comment__c,Type__c,Opportunity.Owner.SubCompany__c,Opportunity.AccountId from Quote where Id =:qId ];
                if(q == null ){
                    setErr('页面打开错误!');
                }else if(q.Status == '申请中' || q.Status == '已批准'){
                    setErr('报价在审批中或已批准不能修改!');
                }
                company = q.Opportunity.Owner.SubCompany__c;
                province = q.Opportunity.Owner.PriceProvince__c;
               // accId = q.Opportunity.ExecutiveCompany__r.RecordType.DeveloperName == 'Maccura' ? q.Opportunity.AccountId :q.Opportunity.ExecutiveCompany__c;
               // if(q.Opportunity.RecordType.DeveloperName == 'DealerOpportunity') accId = q.Opportunity.AccountId;
                backId = qId;
                oppId = q.OpportunityId;
                opp = [select StageName , RecordType.DeveloperName,Id,Owner.SubCompany__c,AccountId ,Account.Name from Opportunity where Id =:oppId];
                accId = opp.AccountId;

            }else if(oppId != null ){//新建
                opp = [select StageName,Owner.PriceProvince__c , RecordType.DeveloperName,Id,Owner.SubCompany__c,AccountId,Account.Name  from Opportunity where Id =:oppId];
                 //是否需要选择适用客户
                if(opp.StageName != '立项' && opp.StageName != '招标' && opp.StageName != '方案谈判' && opp.StageName != '意向'  )setErr('不能在业务机会的'+opp.StageName+'阶段仪器报价');

                if(opp != null){
                    q.OpportunityId = opp.Id;
                    q.Status = '草案中';
                    accId =  opp.AccountId ;
                    if(accId == null ) {
                        setErr('请设置业务机会的客户名!');

                    }
                    q.RecordTypeId = Utils.getRecordTypeIdByDevNameAndObjName('TerminalCustomerReagentQuote','Quote');

                }else{
                    setErr('页面打开错误!');

                }
                 //是否需要选择适用客户

                backId = oppId;
                company = opp.Owner.SubCompany__c;
                province = opp.Owner.PriceProvince__c;
                isNew = true;
                q.ApplicableCustomers__c= opp.AccountId;

            }else {
               
               setErr('页面打开错误!');

            }
            
            aplicableInstrumentcombbox = getOptMap(ImportObject.getPicklistValues('Product__c', 'ApplicableInstrumentModel__c', true));

            System.debug('QuoteRegentController==>'+opp);
            isNeedSelectAccount = (opp.RecordType.DeveloperName == 'DealerOpportunity') ? true  : false  ;
            Account acc = [select Id,ParentId ,Name,System__c,Parent.AccountNumber  from Account where Id =:accId];
            isGPO = acc.Parent.AccountNumber  == '301133';
            parentId = acc.ParentId;
            getIntentTerinalAccount();
             if(q.Name == null) q.Name = acc.Name + '报价-' + Utils.date2string(System.now(), 'YYYYMMDDHHMMSS'); 
             if(q.Type__c == null ) q.Type__c = '试剂报价';
            if(opp.StageName == '合同签订' || opp.StageName == '市场管理' || opp.StageName == '提起合作确认' || opp.StageName == '失败' )setErr('业务机会在'+ opp.StageName +'阶段,不能新建/修改报价 !');
            isSys = isThrid(acc); 
            isBM = checkIsBM(acc );
             dataOpts = 'FromProduct';
            if(!isSys && !isGPO){
                dataOpts = 'FromProduct;PriceProduct';
            }else{
                dataOpts = 'FromProduct;ParentProduct;PriceProduct';
            }
             
            
            companycode = ImportObject.getPicklistValues('Contract__c','Corpcode__c',false).get(company);
            sealflag  =  'Y-'+ companycode;
            salescode = ImportObject.getPicklistValues('PriceList__c', 'SalesCode__c', false).get(company);

        }catch(Exception e ){
             ApexPages.addMessage( new ApexPages.Message(ApexPages.Severity.ERROR ,e.getMessage()));
             isErr = true;

        }
        


    }
     //是否为第三方客户
    private boolean isThrid(Account acc ){
        if(acc == null)return false;
        if(acc.System__c != null) return true;
        return false;
    }
    public String getOptMap(Map<String,String> opts){
       Map<String ,Object> cooMap = new Map<String ,Object> ();
      cooMap.put('valueField', 'value');
      cooMap.put('textField', 'label');
      cooMap.put('panelHeight', 'auto');
      cooMap.put('limitToList', 'true');
      List<Map<String,String>>  dList = new List<Map<String,String>>();
      for (String k : opts.keySet()) {
        Map<String ,String> dataMap = new Map<String,String>();
        dataMap.put('label',opts.get(k) );
        dataMap.put('value',k );
        dList.add(dataMap);
      }  
      cooMap.put('data', dList);   
      
      return EncodingUtil.urlEncode(JSON.serialize(cooMap), 'UTF-8');
    }
    
    public void setApplicableCustomers(){
        appAccId = q.ApplicableCustomers__c;
        System.debug('setApplicableCustomers==>'+ appAccId);
    }

    ///获取报价中的明细
    public void getDetails(){
        if(q.Id != null ){///编辑
            getProductFromQuoteBean(q.Id,false );
        }else{//如果是新建
            System.debug('***'+OppId);
        ///查询是否有上次审批通过的试剂报价 如果有则带入产品及报价;如果没有则带入业务机会中的试剂产品
            List<Quote> qList = [select Id from Quote where OpportunityId =:oppId and Status = '已批准' and Type__c='试剂报价' order by lastmodifieddate desc ];
                    System.debug('***'+qList);

            if(qList.size() > 0){///从上次带入
                System.debug('上次');
                getProductFromQuoteBean(qList[0].Id,true);
            }else{///从意向产品带入
                getProductFromIntent(oppId);
            }
        }
    }

     private void getIntentTerinalAccount(){
       Map<String,String> accMap = new Map<String,String>();

        for(IntentProduct__c ip : [select TerminalClient__c,TerminalClient__r.Name from IntentProduct__c where Opportunity__c =:q.OpportunityId  and TerminalClient__c != null ]){

            accMap.put(ip.TerminalClient__r.Name,ip.TerminalClient__c );
        }
        accMapJson = JSON.serialize(accMap);

    }
    ///从报价中获取产品并生成中间Bean 
    public void getProductFromQuoteBean(String qouteId,Boolean isLast ){

        List<QuoteProductBean> tmp = new List<QuoteProductBean>();

         List<QuoteProduct__c> qpList = getProductFromQuote(qouteId);
        paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');
         if(qpList == null || qpList.size() == 0)return;
         Set<Id>  pset= new Set<Id>();
         System.debug('***'+qpList);
         Set<Id>  maccuras= new Set<Id>();
        for(QuoteProduct__c  qp : qpList){
            pset.add(qp.Product__c);
            if(MaccuraBrandUtil.maccura.contains(qp.Product__r.Brand__c))maccuras.add(qp.Product__c);
        }
        //String companyName =  !isGPO&& isSys  ? '迈克生物股份有限公司':company;
        //Map<Id,Price__c> prMap = !isGPO&& isSys  ? ImportObject.getPriceMap(pset, companyName) : ImportObject.getPriceMap(pset, companyName,province);

        Map<Id,Price__c> prMap = ImportObject.getPriceMap(pset, company,province);
        Map<Id,AveragePrice__c> lastprMap  = ImportObject.getLastMothPrice(pset,company,province);
        Map<Id,QuoteProduct__c> lastQuotePriceMap =  getLastQuotePrice(oppId);
        System.debug('getProductFromQuoteBean==>'+ appAccId + ' '+ accId);
        Map<Id,PriceList__c> priceListMap = ImportObject.getPriceListMap(pset, accId,appAccId, salescode,company,false);
        Map<Id,PriceList__c> sysPriceListMap = new Map<Id,PriceList__c>();
        Map<Id,Price__c> maccuraPrMap = !isSys ||maccuras.isEmpty() ?new  Map<Id,Price__c>():   ImportObject.getPriceMap(maccuras, '迈克生物股份有限公司',false);

        if(parentId != null ) syspriceListMap = ImportObject.getPriceListMap(pset, parentId, salescode,company,true);
        for(QuoteProduct__c qp :qpList){
            tmp.add(new QuoteProductBean(qp,maccuraPrMap.containsKey(qp.Product__c) ? maccuraPrMap.get(qp.Product__c) :  prMap.get(qp.Product__c),lastprMap.get(qp.Product__c),priceListMap.get(qp.Product__c),sysPriceListMap.get(qp.Product__c),lastQuotePriceMap.get(qp.Product__c),isLast,isSys));
        }

        paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');
        System.debug(paramJson);
    }

    ///从报价中获取产品
    public  List<QuoteProduct__c> getProductFromQuote(String qouteId){
        System.debug(qouteId);
        List<QuoteProduct__c> qpList = new List<QuoteProduct__c>();
         qpList = [select Id,Product__c ,Product__r.Name,Product__r.Unit__c,Product__r.Brand__c,Product__r.Model__c,Product__r.ProductName__c,
                Product__r.Category1__c,Product__r.Category2__c,Product__r.Category0__c,Product__r.zl__c,Product__r.TypeName__c,Product__r.ApplicableInstrumentModel__c, 

                Product__r.GroupDeclarationDealerPrice__c,Product__r.GroupProvincialAgencyPrice__c,Product__r.GroupRegionalDistributorsPrice__c,
                Product__r.GroupTerminalGuidePric__c,Product__r.GroupMarketPrice__c,Product__r.GroupSpecialPrice__c,Product__r.swjhdj__c,

                Product__r.NCCode__c,Product__r.SerialNo__c,Product__r.Spec__c ,SalesPrice__c 
             from QuoteProduct__c where Quote__c =:qouteId ];
         return qpList;    

    }
    //从意向产品中获取产品
    public void getProductFromIntent(String opId){
        
        String sql = 'select Id,Product__c,Product__r.Unit__c,Product__r.ProductName__c ,Product__r.Name,Product__r.Brand__c,Product__r.Model__c, '+
                'Product__r.Category1__c,Product__r.Category2__c,Product__r.Category0__c,Product__r.zl__c,Product__r.TypeName__c, '+
                 'Product__r.GroupDeclarationDealerPrice__c,Product__r.GroupProvincialAgencyPrice__c,Product__r.GroupRegionalDistributorsPrice__c,'+
                'Product__r.GroupTerminalGuidePric__c,Product__r.GroupMarketPrice__c,Product__r.GroupSpecialPrice__c,Product__r.swjhdj__c,'+

                'Product__r.NCCode__c,Product__r.SerialNo__c,Product__r.Spec__c ,Product__r.ApplicableInstrumentModel__c '+
             'from IntentProduct__c where Opportunity__c  =\''+opId+'\'  and Product__r.Category0__c not in '+Label.EuipmentCategory0 ;

         if(isBM ){

                sql += ' and Product__r.Brand__c  not in '+ MaccuraBrandUtil.getMaccuraInStr() + '  and   Product__r.NCCode__c not in ' + MaccuraBrandUtil.getMaccuraInStr()  ;
                
         }
        List<IntentProduct__c> ipList = Database.query(sql);


        List<QuoteProductBean> tmp = new List<QuoteProductBean>();
        paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');
        if(ipList == null || ipList.size() == 0)return;
         Set<Id>  pset= new Set<Id>();
         Set<Id>  maccuras= new Set<Id>();
        for(IntentProduct__c  qp : ipList){
            if(MaccuraBrandUtil.maccura.contains(qp.Product__r.Brand__c))maccuras.add(qp.Product__c);

            pset.add(qp.Product__c);
        }
        //String companyName =  !isGPO&& isSys  ? '迈克生物股份有限公司':company;
        Map<Id,Price__c> maccuraPrMap = !isSys ||  maccuras.isEmpty() ?new  Map<Id,Price__c>():   ImportObject.getPriceMap(maccuras, '迈克生物股份有限公司',false);

       // Map<Id,Price__c> prMap =  !isGPO&& isSys  ?  ImportObject.getPriceMap(pset, companyName) : ImportObject.getPriceMap(pset, companyName,province);
        Map<Id,Price__c> prMap = ImportObject.getPriceMap(pset, company,province);
  
        Map<Id,AveragePrice__c> lastprMap  = ImportObject.getLastMothPrice(pset,company,province);
        Map<Id,PriceList__c> sysPriceListMap = new Map<Id,PriceList__c>();
        Map<Id,PriceList__c> priceListMap = ImportObject.getPriceListMap(pset,accId,appAccId,salescode,company,false);

        if(parentId != null ) syspriceListMap = ImportObject.getPriceListMap(pset, parentId, salescode,company,true);
        for(IntentProduct__c qp :ipList){
            tmp.add(new QuoteProductBean(qp,maccuraPrMap.containsKey(qp.Product__c) ? maccuraPrMap.get(qp.Product__c ) :  prMap.get(qp.Product__c),lastprMap.get(qp.Product__c),priceListMap.get(qp.Product__c ),syspriceListMap.get(qp.Product__c),isSys) );
        }
        paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');

    }
    //获取上次审批通过的产品报价价格
    public Map<Id,QuoteProduct__c> getLastQuotePrice(String opId){
        Map<Id,QuoteProduct__c> quotePriceMap = new Map<Id,QuoteProduct__c>();
        List<Quote> qList = [select Id from Quote where OpportunityId =:opId and Status = '已批准' and Type__c='试剂报价' order by lastmodifieddate desc ];
        if(qList.size() == 0)return quotePriceMap;
        System.debug('***'+qList);
         List<QuoteProduct__c> qpList= getProductFromQuote(qList[0].Id);
         for (QuoteProduct__c q : qpList) {
             quotePriceMap.put(q.Product__c,q);
         }
         return quotePriceMap;

    }

    ///从产品中选择
    public void getProduct(){
        

        String sql = 'select Id,Name,ProductName__c ,Unit__c,brand__c,Spec__c ,SerialNo__c ,Model__c ,NCCode__c,Category1__c,Category2__c,Category0__c,zl__c,SealCompany__c ,TypeName__c,ApplicableInstrumentModel__c,';
            sql +='GroupDeclarationDealerPrice__c,GroupProvincialAgencyPrice__c,GroupRegionalDistributorsPrice__c,';
            sql +='GroupTerminalGuidePric__c,GroupMarketPrice__c,GroupSpecialPrice__c,swjhdj__c';

         sql += ' from Product__c where  RecordType.DeveloperName = \'NCProduct\' and NCCode__c != null and PriceCompany__c like \'%'+companycode+'%\'  and Category0__c not  in ' +Label.EuipmentCategory0 ;
        if(!isCouldFindOverseaProduct) sql += ' and  Overseasproducts__c != true  ';
         if(isBM ){

                sql += ' and Brand__c  not in '+ MaccuraBrandUtil.getMaccuraInStr() + '  and   NCCode__c not in ' + MaccuraBrandUtil.getMaccuraInStr()  ;
                
            }

         if(String.isBlank(pname) == false ) sql += ' and Name like \'%'+pname+'%\' ';
         if(String.isBlank(pbrand) == false ) sql += '  and Brand__c like \'%'+pbrand+'%\' ';
         if(String.isBlank(pspec) == false ) sql += '  and Spec__c like \'%'+pspec+'%\' ';
         if(String.isBlank(pnccode) == false ) sql += '  and NCCode__c like \'%'+pnccode+'%\' ';
         if(String.isBlank(pcategory0) == false ) sql += '  and Category0__c like \'%'+pcategory0+'%\' ';
         if(String.isBlank(pcategory1) == false ) sql += '  and Category1__c like \'%'+pcategory1+'%\' ';
         if(String.isBlank(pserialNo) == false ) sql += '  and SerialNo__c like \'%'+pserialNo+'%\' ';
         if(String.isBlank(productType) == false ) sql += '  and TypeName__c like \'%'+productType+'%\' ';
         if(String.isBlank(papplication) == false ) sql += '  and ApplicableInstrumentModel__c includes (\''+papplication+'\') ';


         sql +=' limit 300 ';


        List<Product__c>pList = Database.query(sql);
        System.debug(sql);
        System.debug(pList);
        List<QuoteProductBean> tmp = new List<QuoteProductBean>();
        if(pList == null || pList.size() == 0){
            paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');
            return;
         }
        Set<Id>  pids= new Set<Id>();
        Set<Id>  maccuras= new Set<Id>();

        for(Product__c p :pList){
            if(p.SealCompany__c != null && p.SealCompany__c.contains(sealflag)) continue;
            pids.add(p.Id);
            if(MaccuraBrandUtil.maccura.contains(p.Brand__c))maccuras.add(p.Id);
        }
        //String companyName =  !isGPO&& isSys  ? '迈克生物股份有限公司':company;

        //Map<Id,Price__c> prMap =!isGPO&& isSys  ? ImportObject.getPriceMap(pids, companyName) : ImportObject.getPriceMap(pids, companyName,province);
        Map<Id,Price__c> prMap = ImportObject.getPriceMap(pids, company,province);
        Map<Id,Price__c> maccuraPrMap = !isSys || maccuras.isEmpty() ?new  Map<Id,Price__c>():   ImportObject.getPriceMap(maccuras, '迈克生物股份有限公司',false);
        Map<Id,AveragePrice__c> lastprMap  = ImportObject.getLastMothPrice(pids, company,province);
                System.debug('getProductFromQuoteBean==>'+ appAccId + ' '+ accId);

        Map<Id,PriceList__c> priceListMap = ImportObject.getPriceListMap(pids,accId,appAccId,salescode,company,false);
        Map<Id,PriceList__c> sysPriceListMap = new Map<Id,PriceList__c>();

        if(parentId != null) sysPriceListMap = ImportObject.getPriceListMap(pids, parentId,salescode,company,true);

        for(Product__c p :pList){
            if(p.SealCompany__c != null && p.SealCompany__c.contains(sealflag)) continue;
            if(prMap.get(p.Id) == null) continue;
            tmp.add(new QuoteProductBean(p,maccuraPrMap.containsKey(p.Id ) ? maccuraPrMap.get(p.Id  ) : prMap.get(p.Id),lastprMap.get(p.Id),priceListMap.get(p.Id),sysPriceListMap.get(p.Id),isSys));

        }
        
        paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');
    }

   public void getProductFromPriceList(String acId,Boolean isParent){
        
        String sql = 'select Product__c, Product__r.Unit__c,Product__r.Brand__c,Product__r.Spec__c,Product__r.SerialNo__c,Product__r.Model__c ,Product__r.ProductName__c,';
            sql += 'Product__r.Category1__c,Product__r.Category2__c,Product__r.Category0__c,Product__r.zl__c,Product__r.NCCode__c,';
            sql +=  'Product__r.GroupDeclarationDealerPrice__c,Product__r.GroupProvincialAgencyPrice__c,Product__r.GroupRegionalDistributorsPrice__c,';
              sql +=    'Product__r.GroupTerminalGuidePric__c,Product__r.GroupMarketPrice__c,Product__r.GroupSpecialPrice__c,Product__r.swjhdj__c,';

            sql += 'Product__r.Name,SalesCode__c,Price__c,Id,Product__r.SealCompany__c ,Product__r.TypeName__c,Product__r.ApplicableInstrumentModel__c  from PriceList__c ';

            sql += ' where Account__c =\''+acId+'\' ';

             if(isBM ){

                sql += ' and Product__r.Brand__c  not in '+ MaccuraBrandUtil.getMaccuraInStr() + '  and   Product__r.NCCode__c not in ' + MaccuraBrandUtil.getMaccuraInStr()  ;
                
            }

            if(!isParent)sql +=' and  SalesCode__c=\''+salescode+'\' and Company__c = \''+company+'\' ' ;

            if(appAccId != null &&  appAccId != acId && !isParent )sql  += ' and ApplicableCustomers__c =\''+appAccId+'\'' ;
            if(appAccId != null &&  appAccId == acId && !isParent )sql  += ' and (ApplicableCustomers__c =\''+appAccId+'\' or ApplicableCustomers__c = null ) ' ;

            System.debug('***'+sql);
            
         
         if(String.isBlank(pname) == false ) sql += ' and Product__r.Name like \'%'+pname+'%\' ';
         if(String.isBlank(pbrand) == false ) sql += '  and Product__r.Brand__c like \'%'+pbrand+'%\' ';
         if(String.isBlank(pspec) == false ) sql += '  and Product__r.Spec__c like \'%'+pspec+'%\' ';
         if(String.isBlank(pnccode) == false ) sql += '  and Product__r.NCCode__c like \'%'+pnccode+'%\' ';
         if(String.isBlank(pcategory0) == false ) sql += '  and Product__r.Category0__c like \'%'+pcategory0+'%\' ';
         if(String.isBlank(pcategory1) == false ) sql += '  and Product__r.Category1__c like \'%'+pcategory1+'%\' ';
         if(String.isBlank(pserialNo) == false ) sql += '  and Product__r.SerialNo__c like \'%'+pserialNo+'%\' ';
         if(String.isBlank(papplication) == false ) sql += '  and Product__r.ApplicableInstrumentModel__c includes (\''+papplication+'\') ';

         System.debug('-->' +sql);
         List<PriceList__c> pList = Database.query(sql);
        List<QuoteProductBean> tmp = new List<QuoteProductBean>();
         if(pList == null || pList.size() == 0){
            paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');
            return;
         }
        Set<Id>  maccuras= new Set<Id>();
         Set<Id>  pids = new Set<Id>();
         for (PriceList__c p : pList) {
             if(p.Product__r.SealCompany__c != null && p.Product__r.SealCompany__c.contains(sealflag)) continue;
            if(MaccuraBrandUtil.maccura.contains(p.Product__r.Brand__c))maccuras.add(p.Product__c);

            pids.add(p.Product__c);
         }
        //String companyName =  !isGPO&& isSys  ? '迈克生物股份有限公司':company;

        //Map<Id,Price__c> prMap = !isGPO&& isSys  ?ImportObject.getPriceMap(pids,companyName) : ImportObject.getPriceMap(pids,companyName,province);
        Map<Id,Price__c> prMap = ImportObject.getPriceMap(pids, company,province);
        Map<Id,Price__c> maccuraPrMap = !isSys || maccuras.isEmpty() ?new  Map<Id,Price__c>():   ImportObject.getPriceMap(maccuras, '迈克生物股份有限公司',false);

        Map<Id,AveragePrice__c> lastprMap  = ImportObject.getLastMothPrice(pids,company,province);
        Map<Id,PriceList__c> sysPriceListMap = new Map<Id,PriceList__c>();
        if(parentId != null) sysPriceListMap = ImportObject.getPriceListMap(pids, parentId,salescode,company,true);
        for(PriceList__c p :pList){
             if(p.Product__r.SealCompany__c != null && p.Product__r.SealCompany__c.contains(sealflag)) continue;
                AveragePrice__c ap = lastprMap.get(p.Product__c);
            if(lastMothOpt != null && lastMothOpt != ''){
                if(lastMothOpt == '<' && (ap == null || ap.AveragePrice__c == null  || ap.AveragePrice__c >= p.Price__c ))continue;///低于
                if(lastMothOpt == '>' && (ap == null || ap.AveragePrice__c == null  ||  ap.AveragePrice__c <= p.Price__c ))continue;///高于
                if(lastMothOpt == 'no' && (ap != null && ap.AveragePrice__c != null) ) continue;///为空
                if(lastMothOpt == '=' && (ap == null ||  ap.AveragePrice__c != p.Price__c ))continue;///等于
                
            }
            tmp.add(new QuoteProductBean(p,maccuraPrMap.containsKey(p.Product__c) ? maccuraPrMap.get(p.Product__c): prMap.get(p.Product__c),ap,sysPriceListMap.get(p.Product__c), isSys ));
        }
        

        paramJson = EncodingUtil.urlEncode(JSON.serialize(tmp),  'UTF-8');
    }
    public void search(){
        pname = '';
        pbrand = '';
        pspec = '';
        pnccode = '';
        pserialNo = '';
        pcategory0 = '';
        pcategory1 = '';
        lastMothOpt = '';
        productType = '';
        papplication = '';

        System.debug('***'+searchJson); 
        //System.debug('***'+EncodingUtil.urlDecode(searchJson, 'UTF-8')); 
        Map<String,Object> searchMap =(Map<String,Object> )JSON.deserializeUntyped(EncodingUtil.urlDecode(searchJson, 'UTF-8'));
        String type = String.valueOf(searchMap.get('type')) ;
        String productName =  String.valueOf(searchMap.get('productName')) ;
        String brand =  String.valueOf(searchMap.get('brand')) ;
        String spec =  String.valueOf(searchMap.get('spec') );
        String cate0 =  String.valueOf(searchMap.get('cate0')) ;
        String nccode =  String.valueOf(searchMap.get('nccode')) ;
        String cate1=  String.valueOf(searchMap.get('cate1') );
        String serialNo=  String.valueOf(searchMap.get('serialNo') );
         lastMothOpt=  String.valueOf(searchMap.get('lastMothOpt') );
        String ptype=  String.valueOf(searchMap.get('ptype') );


        if( productName != null && productName != '')pname = productName;
        if( brand != null && brand != '')pbrand = brand;
        if( spec != null && spec != '')pspec = spec;
        if( cate0 != null && cate0 != '')pcategory0 = cate0;
        if( cate1 != null && cate1 != '')pcategory1 = cate1;
        if( nccode != null && nccode != '')pnccode = nccode;
        if( serialNo != null && serialNo != '')pserialNo = serialNo;
        if( ptype != null && ptype != '')productType = ptype;
        if(String.isNotBlank(String.valueOf(searchMap.get('application')))) papplication = String.valueOf(searchMap.get('application'));


        if(type == 'FromProduct'){//从产品中选择
            getProduct();
        }else if(type == 'ParentProduct'){//体系价目表中选择
            getProductFromPriceList(parentId,true);

        }else if(type == 'PriceProduct'){//从价目表中选择
            getProductFromPriceList(accId,false);

        }
    }

     ///置空参数
    public void setNil(){
        paramJson = '';
        searchJson = '';
        resJson = '[]'; 
        pname = '';
        pbrand = '';
        pspec = '';
        pnccode = '';
        pcategory0 = '';
        pcategory1 = '';
    }

    ///保存
    public void save(){

        msg = '';
        System.debug('**'+resJson);
        List<Object> resList=(List<Object>)JSON.deserializeUntyped(EncodingUtil.urlDecode(resJson, 'UTF-8'));
            
        if(resList.size() == 0){
            msg = '保存失败,没有数据!';
            return;
        }
        //Set<String>  pros= getExistProdcut(accId,false);
        //System.debug('***'+pros);
        SavePoint sp = Database.setSavepoint();
        try {
            if(isNew)q.Id = null ;
            upsert q;

            Set<String> prosets = new Set<String>();
            List<QuoteProduct__c> apList = new List<QuoteProduct__c>();
            System.debug('+++'+resList);
            for (Object res : resList) {
                Map<String ,Object> o = (Map<String ,Object> )res;
                QuoteProduct__c qp = new QuoteProduct__c();
                
                String productId = o.get('productId') == null ? null : String.valueOf(o.get('productId'));
                if(productId == null ){
                    msg = o.get('productName') +'的产品ID为空,不能保存!';
                    break;
                }else{
                    prosets.add(productId);
                    qp.Product__c = productId;
                }
                if(o.get('productName') != null ){
                    qp.Name = String.valueOf(o.get('productName'));
                }
                if(o.get('adprice') != null ){
                    qp.SalesPrice__c = getDecimalValue(o.get('adprice'));
                }else{
                    msg = o.get('productName')+ '产品的本次报价必填!';
                    break;
                        
                }

                if(o.get('provincialAgencyPrice') != null ) qp.ProvincialAgencyPrice__c =  getDecimalValue(o.get('provincialAgencyPrice'));
                if(o.get('invoiceDealerPrice') != null ){
                    qp.InvoiceDealerPrice__c = getDecimalValue(o.get('invoiceDealerPrice'));
                }

                if(o.get('areaDealerPrice') != null ){
                    qp.AreaDealerPrice__c = getDecimalValue(o.get('areaDealerPrice'));
                }
                 qp.InstCost__c = getDecimalValue(o.get('instCost'));

                 Decimal sysPrice = getDecimalValue(o.get('sysPrice'));
                if( (qp.InstCost__c  == null ||  qp.InstCost__c == 0) && (sysPrice == null || sysPrice == 0 )  ){
                    msg += o.get('productName') +'--' + o.get('nccode') +',没有成本价!\n';
                }

                if(o.get('companyBottomPrice') != null ){
                    qp.CompanyBottomPrice__c = getDecimalValue(o.get('companyBottomPrice'));
                }
                if(o.get('hospitalManagerPrice') != null ){
                    qp.HospitalManagerPrice__c = getDecimalValue(o.get('hospitalManagerPrice'));
                }
                if(o.get('lastMothPrice') != null ){
                    qp.LastMonthAveragePrice__c = getDecimalValue(o.get('lastMothPrice'));
                }
                if(o.get('marketPrice') != null ){
                    qp.UnitPrice__c = getDecimalValue(o.get('marketPrice'));
                }
               

                if(o.get('cate0') != null ){
                    qp.Category0__c = String.valueOf(o.get('cate0'));
                }
                if(o.get('cate1') != null ){
                    qp.Category1__c =String.valueOf(o.get('cate1'));
                }
                if(o.get('cate2') != null ){
                    qp.Category2__c = String.valueOf(o.get('cate2'));
                }
                if(o.get('spec') != null ){
                    qp.Spec__c = String.valueOf(o.get('spec'));
                }
                if(o.get('brand') != null ){
                    qp.Brand__c = String.valueOf(o.get('brand'));
                }
                if(o.get('serialNo') != null ){
                    qp.SerialNo__c = String.valueOf(o.get('serialNo'));
                }
                if(o.get('model') != null ){
                    qp.Model__c = String.valueOf(o.get('model'));
                }
                if(o.get('discount') != null ){
                    qp.DiscountRate__c = getDecimalValue(o.get('discount'));
                }
                if(o.get('specialprice') != null ){
                    qp.SpecialPrice__c = getDecimalValue(o.get('specialprice'));
                }
                //保存gpo价格
                if(isGPO && o.get('sysPrice') != null )qp.GPOPrice__c = sysPrice;
                if(!isGPO && o.get('sysPrice') != null )qp.SystemPrice__c = sysPrice;
                if(o.get('price') != null )qp.OriginalPrice__c = getDecimalValue(o.get('price'));

                qp.Quote__c = q.Id;
                //qp.Account__c = accId;
                apList.add(qp);

            }

            ///验证中是否存在调价的产品
            System.debug('***' + apList);
            if(msg.length() > 0) return;
            List<QuoteProduct__c> deleList = [select Id from QuoteProduct__c where Quote__c =: q.Id];
            if(deleList != null && deleList.size() > 0) delete deleList;
            insert apList;
            backId = q.Id;
            isSuccess = true;
        }catch(Exception e) {
            Database.rollback(sp);
            isSuccess = false;
            System.debug('***'+e);
            msg = '保存失败!' +e.getMessage();

        }
    }

     private Decimal getDecimalValue(Object val){
        if(val == null)return null;
        String  d = String.valueOf(val);
        if(d == '')return null;
        return Decimal.valueOf(d.trim());
    }

     //中间Bean 
    public class  QuoteProductBean{
        public String productId {get;set;}//产品ID
        public String productName {get;set;}//产品名称
        public String brand {get;set;}//品牌
        public String  spec {get;set;}//规格
        public String  serialNo {get;set;}//货号
        public String  model {get;set;}//型号
        public String  nccode {get;set;}//存货编码
        public String  productType {get;set;}//产品类型
        public String unit ;

        public Decimal price {get;set;}//单价
        public Decimal sysPrice {get;set;}//第三方体系价

        public Decimal adprice {get;set;} //调整价格
        public Decimal discount {get;set;}//折扣率

        public String cate0 {get;set;}//主分类
        public String cate1 {get;set;}//一级分类
        public String cate2 {get;set;}//二级分类

        public String zl  {get;set;}//装量
        public Decimal taxrate {get;set;}//税率

        public Decimal lastQuotePrice {get;set;}///上次报价

        public Decimal companyBottomPrice {get;set;}//公司底价
        public Decimal areaDealerPrice {get;set;}//区域经销商价
        public Decimal instCost {get;set;}//成本价
        public Decimal invoiceDealerPrice {get;set;}//报价经销商价
        public Decimal hospitalManagerPrice {get;set;}//终端指导价
        public Decimal provincialAgencyPrice;

        public Decimal marketPrice {get;set;}//市场报价

        public Boolean isHasLastMothPrice {get;set;}//是否有上月平均价
        public Decimal lastMothPrice {get;set;}//上月平均价
        public Decimal specialprice ;//特级经销商价
        public Decimal orlprice ; //原单价
        public Decimal gpoprice ;//gpo 价格

        public String application;//适用机型 


        public QuoteProductBean(QuoteProduct__c p,Price__c pr,AveragePrice__c ap ,PriceList__c pl ,PriceList__c syspl,QuoteProduct__c lastQ,Boolean isLast,Boolean isThrid ){
            productId = p.Product__c;
            productName = p.Product__r.ProductName__c;
            spec = p.Product__r.Spec__c;
            model = p.Product__r.Model__c;
            serialNo = p.Product__r.SerialNo__c;
            nccode = p.Product__r.NCCode__c;
            brand = p.Product__r.Brand__c;
            unit = p.Product__r.Unit__c;

            cate0 = p.Product__r.Category0__c;
            cate1 = p.Product__r.Category1__c;
            cate2 = p.Product__r.Category2__c;
            productType = p.Product__r.TypeName__c;
            application = p.Product__r.ApplicableInstrumentModel__c;
            zl = p.Product__r.zl__c;
            if(pr == null ) pr = new Price__c();
            adprice = isLast == true ? null : p.SalesPrice__c;
            if(lastQ != null )lastQuotePrice = lastQ.SalesPrice__c;
            if(syspl != null )sysPrice = syspl.Price__c;
            if(pl != null )price = pl.Price__c;
           
            taxrate  = pr.Taxrate__c;
            companyBottomPrice = pr.CompanyBottomPrice__c;
            areaDealerPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupRegionalDistributorsPrice__c :  pr.AreaDealerPrice__c;
            instCost =  pr.InstCost__c;
            invoiceDealerPrice = isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupDeclarationDealerPrice__c : pr.InvoiceDealerPrice__c;
            hospitalManagerPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupTerminalGuidePric__c :  pr.HospitalManagerPrice__c;
            marketPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupMarketPrice__c :  pr.MarketPrice__c;
            specialprice = isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupSpecialPrice__c : pr.SpecialPrice__c;
            provincialAgencyPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupProvincialAgencyPrice__c :  pr.ProvincialAgencyPrice__c;

            
            isHasLastMothPrice = ap!=  null;
            if(ap != null )lastMothPrice = ap.AveragePrice__c;

        }
        public QuoteProductBean(IntentProduct__c p,Price__c pr,AveragePrice__c ap ,PriceList__c pl ,PriceList__c syspl ,Boolean isThrid){
            productId = p.Product__c;
            productName = p.Product__r.ProductName__c;
            spec = p.Product__r.Spec__c;
            model = p.Product__r.Model__c;
            serialNo = p.Product__r.SerialNo__c;
            nccode = p.Product__r.NCCode__c;
            brand = p.Product__r.Brand__c;
            unit = p.Product__r.Unit__c;

            cate0 = p.Product__r.Category0__c;
            cate1 = p.Product__r.Category1__c;
            cate2 = p.Product__r.Category2__c;
            productType = p.Product__r.TypeName__c;
            application = p.Product__r.ApplicableInstrumentModel__c;
            zl = p.Product__r.zl__c;
            if(pr == null ) pr = new Price__c();
            if(pl != null )price = pl.Price__c;
            if(syspl != null )sysPrice = syspl.Price__c;
            
            taxrate  = pr.Taxrate__c;
            companyBottomPrice = pr.CompanyBottomPrice__c;
            // areaDealerPrice = pr.AreaDealerPrice__c;
            // instCost = pr.InstCost__c;
            // invoiceDealerPrice = pr.InvoiceDealerPrice__c;
            // hospitalManagerPrice = pr.HospitalManagerPrice__c;
            // marketPrice = pr.MarketPrice__c;
            // specialprice = pr.SpecialPrice__c;
            // provincialAgencyPrice = pr.ProvincialAgencyPrice__c;

            areaDealerPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupRegionalDistributorsPrice__c :  pr.AreaDealerPrice__c;
            instCost =  pr.InstCost__c;
            invoiceDealerPrice = isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupDeclarationDealerPrice__c : pr.InvoiceDealerPrice__c;
            hospitalManagerPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupTerminalGuidePric__c :  pr.HospitalManagerPrice__c;
            marketPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupMarketPrice__c :  pr.MarketPrice__c;
            specialprice = isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupSpecialPrice__c : pr.SpecialPrice__c;
            provincialAgencyPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupProvincialAgencyPrice__c :  pr.ProvincialAgencyPrice__c;
            
            isHasLastMothPrice = ap!=  null;
            if(ap != null )lastMothPrice = ap.AveragePrice__c;

        }
        public QuoteProductBean(Product__c p,Price__c pr,AveragePrice__c ap ,PriceList__c pl ,PriceList__c syspl,Boolean isThrid){
            productId = p.Id ;
            productName = p.ProductName__c ;
            spec = p.Spec__c;
            model = p.Model__c;
            serialNo = p.SerialNo__c;
            nccode = p.NCCode__c;
            brand = p.Brand__c;
            cate0 = p.Category0__c;
            cate1 = p.Category1__c;
            cate2 = p.Category2__c;
             unit = p.Unit__c;

            application = p.ApplicableInstrumentModel__c;
            zl = p.zl__c;
            productType = p.TypeName__c;
            if(syspl != null )sysPrice = syspl.Price__c;
            if(pl != null )price = pl.Price__c;

            if(pr == null ) pr = new Price__c();
           
            taxrate  = pr.Taxrate__c;
            companyBottomPrice = pr.CompanyBottomPrice__c;
            // areaDealerPrice = pr.AreaDealerPrice__c;
            // instCost = pr.InstCost__c;
            // invoiceDealerPrice = pr.InvoiceDealerPrice__c;
            // hospitalManagerPrice = pr.HospitalManagerPrice__c;
            // marketPrice = pr.MarketPrice__c;
            // specialprice = pr.SpecialPrice__c;
            // provincialAgencyPrice = pr.ProvincialAgencyPrice__c;
             areaDealerPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.GroupRegionalDistributorsPrice__c :  pr.AreaDealerPrice__c;
            instCost =  pr.InstCost__c;
            invoiceDealerPrice = isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.GroupDeclarationDealerPrice__c : pr.InvoiceDealerPrice__c;
            hospitalManagerPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.GroupTerminalGuidePric__c :  pr.HospitalManagerPrice__c;
            marketPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.GroupMarketPrice__c :  pr.MarketPrice__c;
            specialprice = isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.GroupSpecialPrice__c : pr.SpecialPrice__c;
            provincialAgencyPrice =isThrid && MaccuraBrandUtil.maccura.contains(brand) ? p.GroupProvincialAgencyPrice__c :  pr.ProvincialAgencyPrice__c;

            isHasLastMothPrice = ap != null;
            if(ap != null )lastMothPrice = ap.AveragePrice__c;  


        }

        public QuoteProductBean(PriceList__c p,Price__c pr,AveragePrice__c ap, PriceList__c syspl,Boolean isSys ){
            productId = p.Product__c;
            productName = p.Product__r.ProductName__c;
            spec = p.Product__r.Spec__c;
            model = p.Product__r.Model__c;
            serialNo = p.Product__r.SerialNo__c;
            nccode = p.Product__r.NCCode__c;
            brand = p.Product__r.Brand__c;
            application = p.Product__r.ApplicableInstrumentModel__c;
             unit = p.Product__r.Unit__c;

            cate0 = p.Product__r.Category0__c;
            cate1 = p.Product__r.Category1__c;
            cate2 = p.Product__r.Category2__c;
            zl =p.Product__r.zl__c;
            productType = p.Product__r.TypeName__c;
            if(!isSys )price = p.Price__c;
            if(syspl != null)sysPrice = syspl.Price__c;
            if(pr == null ) pr = new Price__c();
            taxrate  = pr.Taxrate__c;
            companyBottomPrice = pr.CompanyBottomPrice__c;
            // areaDealerPrice = pr.AreaDealerPrice__c;
            // instCost = pr.InstCost__c;
            // invoiceDealerPrice = pr.InvoiceDealerPrice__c;
            // hospitalManagerPrice = pr.HospitalManagerPrice__c;
            // marketPrice = pr.MarketPrice__c;
            // provincialAgencyPrice = pr.ProvincialAgencyPrice__c;

             areaDealerPrice =isSys && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupRegionalDistributorsPrice__c :  pr.AreaDealerPrice__c;
            instCost =  pr.InstCost__c;
            invoiceDealerPrice = isSys && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupDeclarationDealerPrice__c : pr.InvoiceDealerPrice__c;
            hospitalManagerPrice =isSys && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupTerminalGuidePric__c :  pr.HospitalManagerPrice__c;
            marketPrice =isSys && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupMarketPrice__c :  pr.MarketPrice__c;
            specialprice = isSys && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupSpecialPrice__c : pr.SpecialPrice__c;
            provincialAgencyPrice =isSys && MaccuraBrandUtil.maccura.contains(brand) ? p.Product__r.GroupProvincialAgencyPrice__c :  pr.ProvincialAgencyPrice__c;
            
            isHasLastMothPrice = ap !=  null;
            if(ap != null )lastMothPrice = ap.AveragePrice__c;
        }
    }








}